// <copyright file="RoleController.cs" company="EnterpriseApi">
// Copyright (c) EnterpriseApi. All rights reserved.
// </copyright>

using EnterpriseApi.DTOs;
using EnterpriseApi.Models;
using EnterpriseApi.Services;
using Microsoft.AspNetCore.Mvc;

namespace EnterpriseApi.Controllers;

/// <summary>
/// 角色控制器，处理角色相关的HTTP请求
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class RoleController : ControllerBase
{
    private readonly IRoleService _roleService;
    private readonly ILogger<RoleController> _logger;

    /// <summary>
    /// 初始化RoleController的新实例
    /// </summary>
    /// <param name="roleService">角色服务</param>
    /// <param name="logger">日志记录器</param>
    public RoleController(IRoleService roleService, ILogger<RoleController> logger)
    {
        _roleService = roleService ?? throw new ArgumentNullException(nameof(roleService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// 获取所有角色
    /// </summary>
    /// <returns>角色列表</returns>
    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<ActionResult<IEnumerable<RoleDTO>>> GetAllRoles()
    {
        try
        {
            var roles = await _roleService.GetAllAsync();
            var roleDTOs = roles.Select(role => new RoleDTO
            {
                Id = role.Id,
                Name = role.Name,
                Description = role.Description,
                CreatedAt = role.CreatedAt,
                UpdatedAt = role.UpdatedAt,
                UserCount = role.Users?.Count ?? 0
            });
            return Ok(roleDTOs);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取所有角色时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "获取所有角色时发生错误");
        }
    }

    /// <summary>
    /// 根据ID获取角色
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>角色详情</returns>
    [HttpGet("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<RoleDTO>> GetRoleById(int id)
    {
        try
        {
            var role = await _roleService.GetByIdAsync(id);
            if (role == null)
            {
                return NotFound();
            }

            var roleDTO = new RoleDTO
            {
                Id = role.Id,
                Name = role.Name,
                Description = role.Description,
                CreatedAt = role.CreatedAt,
                UpdatedAt = role.UpdatedAt,
                UserCount = role.Users?.Count ?? 0
            };
            return Ok(roleDTO);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取角色详情时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "获取角色详情时发生错误");
        }
    }

    /// <summary>
    /// 创建新角色
    /// </summary>
    /// <param name="role">角色信息</param>
    /// <returns>创建的角色</returns>
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<ActionResult<RoleDTO>> CreateRole([FromBody] Role role)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        try
        {
            var createdRole = await _roleService.CreateRoleAsync(role);

            var roleDTO = new RoleDTO
            {
                Id = createdRole.Id,
                Name = createdRole.Name,
                Description = createdRole.Description,
                CreatedAt = createdRole.CreatedAt,
                UpdatedAt = createdRole.UpdatedAt,
                UserCount = createdRole.Users?.Count ?? 0
            };
            return CreatedAtAction(nameof(GetRoleById), new { id = createdRole.Id }, roleDTO);
        }
        catch (ArgumentException ex)
        {
            _logger.LogError(ex, "创建角色时发生错误");
            return BadRequest(ex.Message);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "创建角色时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "创建角色时发生错误");
        }
    }

    /// <summary>
    /// 更新角色信息
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <param name="role">更新的角色信息</param>
    /// <returns>更新后的角色</returns>
    [HttpPut("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<RoleDTO>> UpdateRole(int id, [FromBody] Role role)
    {
        if (id != role.Id)
        {
            return BadRequest("角色ID不匹配");
        }

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        try
        {
            var existingRole = await _roleService.GetByIdAsync(id);
            if (existingRole == null)
            {
                return NotFound();
            }

            role.UpdatedAt = DateTime.UtcNow;
            var updatedRole = await _roleService.UpdateAsync(role);

            var roleDTO = new RoleDTO
            {
                Id = updatedRole.Id,
                Name = updatedRole.Name,
                Description = updatedRole.Description,
                CreatedAt = updatedRole.CreatedAt,
                UpdatedAt = updatedRole.UpdatedAt,
                UserCount = updatedRole.Users?.Count ?? 0
            };
            return Ok(roleDTO);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新角色信息时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "更新角色信息时发生错误");
        }
    }

    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>删除结果</returns>
    [HttpDelete("{id}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> DeleteRole(int id)
    {
        try
        {
            var role = await _roleService.GetByIdAsync(id);
            if (role == null)
            {
                return NotFound();
            }

            // 检查角色下是否有用户
            if (role.Users != null && role.Users.Any())
            {
                return BadRequest("该角色下有用户，不能删除");
            }

            await _roleService.DeleteAsync(id);
            return NoContent();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "删除角色时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "删除角色时发生错误");
        }
    }

    /// <summary>
    /// 根据名称获取角色
    /// </summary>
    /// <param name="name">角色名称</param>
    /// <returns>角色详情</returns>
    [HttpGet("name/{name}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<RoleDTO>> GetRoleByName(string name)
    {
        try
        {
            var role = await _roleService.GetByNameAsync(name);
            if (role == null)
            {
                return NotFound();
            }

            var roleDTO = new RoleDTO
            {
                Id = role.Id,
                Name = role.Name,
                Description = role.Description,
                CreatedAt = role.CreatedAt,
                UpdatedAt = role.UpdatedAt,
                UserCount = role.Users?.Count ?? 0
            };
            return Ok(roleDTO);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "根据名称获取角色时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "根据名称获取角色时发生错误");
        }
    }

    /// <summary>
    /// 检查角色名称是否已存在
    /// </summary>
    /// <param name="name">角色名称</param>
    /// <returns>是否存在的布尔值</returns>
    [HttpGet("exists/{name}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<ActionResult<bool>> IsRoleNameExists(string name)
    {
        try
        {
            var exists = await _roleService.IsNameExistsAsync(name);
            return Ok(exists);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "检查角色名称是否存在时发生错误");
            return StatusCode(StatusCodes.Status500InternalServerError, "检查角色名称是否存在时发生错误");
        }
    }
}